#ifndef USUARIO_H_
#define USUARIO_H_

#define PREFIJO_FIFO "/tmp/fifoConcuShare_"
#define FIFO_DESCARGA_PATH "/tmp/fifoDescarga_"
#define BUFFER_MAX 256

#include <string>
#include <Fifo.h>
#include <sstream>
#include <list>
#include <limits.h>
#include <stdlib.h>
#include <iostream>
#include <sys/wait.h>
#include <SignalHandler.h>
#include "signalHandlers/PUBLISH_FILES_Handler.h"
#include "signalHandlers/UPLOAD_Handler.h"
#include "signalHandlers/EXITCHILD_Handler.h"
#include "../Log.h"

using namespace std;

class Usuario {
private:
	/*
	 * Atributos
	 */

	// Id de sesion del usuario
	int id;

	// Nombre del usuario
	string nombre;

	// Lista de archivos compartidos por el usuario
	list<string> * archivosCompartidos;

	// Lista de procesos de descarga y subida del usuario
	list<int> descargas;
	list<int> subidas;

	// Path a la carpeta de descarga del usuario
	string carpetaDescarga;

	/*
	 * Handlers de señales
	 */

	// Handler para publicar archivos compartidos
	PUBLISH_FILES_Handler* handler;
	// Handler para compartir un archivo con otro usuario
	UPLOAD_Handler* handlerSolicitudDescarga;
	// Handler para cerrar un proceso hijo
	EXITCHILD_Handler* exitchild_handler;

	// Instancia de Usuario
	static Usuario* instance;

	Usuario();
	virtual ~Usuario();

public:

	/*
	 * Obtiene una unica instancia de Usuario
	 */
	static Usuario* getInstance();

	/*
	 * Elimina la instancia
	 */
	static void destroy();

	/*
	 * Devuelve el nombre del usuario
	 */
	string getNombre(){return nombre;};

	/*
	 * Setea el nombre del usuario
	 */
	void setNombre(string nom) {
		this->nombre = nom;
	};

	/*
	 * Devuelve el id del usuario
	 */
	int getId(){return id;};

	/*
	 * Agrega el path a la lista de archivos compartidos
	 */
	void compartirArchivo(string path);

	/*
	 * Devuelve la lista de archivos compartidos por el usuario
	 */
	list<string> misArchivosCompartidos();

	/*
	 * Devuelve la lista de archivos compartidos por el usuario
	 * en un string con posicion y path
	 */
	string mostrarMisArchivosCompartidos();

	/*
	 * Elimina el path de la lista de archivos compartidos
	 */
	void dejarDeCompartir(string path);

	/*
	 * Agrega el pid a la lista de descargas
	 */
	void registrarDescarga(int pid);

	/*
	 * Agrega el pid a la lista de subidas
	 */
	void registrarSubida(int pid);

	/*
	 * Espera que los procesos de subida y descarga hayan finalizado
	 */
	void terminarTransferencias();

	/*
	 * Setea la carpeta de descargas del usuario
	 */
	void setCarpetaDescarga(string path) {
		carpetaDescarga = path;
	};

	/*
	 * Devuelve la carpeta de descargas del usuario
	 */
	string getCarpetaDescarga() {
		return carpetaDescarga;
	};

	/*
	 * Retorna true si el proceso que se interrumpio es hijo
	 * del proceso principal
	 */
	bool exitChild();

	/*
	 * Devuelve el Handler de EXIT CHILD
	 */
	EXITCHILD_Handler* getExitChildHandler(){
		return exitchild_handler;
	};
};

#endif /* USUARIO_H_ */
